/** * 腾讯地图组件 * 用于显示地图、标记点、路线等功能 */
<template>
  <!-- 腾讯地图容器组件 -->
  <tlbs-map
    id="map"
    class="map-container"
    ref="mapRef"
    :apiKey="apiKey"
    :center="center"
    :zoom="zoom"
    :control="control"
    @click="onMapClick"
    @map_inited="onMapInited">
    <!-- 多点标记组件 -->
    <tlbs-multi-marker ref="markerRef" :geometries="geometries" :styles="styles" :options="options" />
    <!-- 路线绘制组件 -->
    <tlbs-multi-polyline
      ref="polilineRef"
      :geometries="p_geometries"
      :styles="styles"
      :options="options"></tlbs-multi-polyline>
  </tlbs-map>
</template>

<script setup name="TMap">
import { onBeforeMount, ref, watch } from 'vue'
import { getLocation, getGeoCoder, getNavDriving } from '../../api/map'

// 定义组件事件
const emit = defineEmits()

// 防抖函数
const debounce = (fn, delay) => {
  let timer = null
  return function (...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

// 组件属性定义
const props = defineProps({
  // 位置信息对象
  location: {
    type: Object,
    default: () => ({})
  },
  // 导航信息对象，包含起点和终点
  navigation: {
    type: Object,
    default: () => ({
      current: null,
      destination: null
    })
  },
  // 是否禁用地图点击
  disabled: {
    type: Boolean,
    default: false
  }
})

// 监听位置变化，触发地理编码
watch(
  () => props.location,
  (newValue, oldValue) => {
    geoCoder()
  }
)
watch(
  () => props.navigation.current,
  newValue => {
    navigation()
  }
)

// 地图相关配置
const apiKey = ref('') // 腾讯地图API密钥
const mapRef = ref({}) // 地图实例引用
const markerRef = ref({}) // 标记点实例引用
const center = ref({ lat: 39.909, lng: 116.397 }) // 地图中心点
const zoom = ref(14) // 地图缩放级别
const control = ref({}) // 地图控件配置

// 样式配置
const styles = ref({
  marker: {
    width: 20,
    height: 30,
    anchor: { x: 10, y: 30 }
  },
  polyline: {
    color: '#2C68FF', // 路线填充色
    borderWidth: 2, // 路线边线宽度
    borderColor: '#004EE1' // 路线边线颜色
  }
})

// 地图选项配置
const options = ref({
  minZoom: 1,
  maxZoom: 20,
  zIndex: 1
})

// 标记点和路线数据
const geometries = ref([]) // 标记点数据
const p_geometries = ref([]) // 路线数据

// 组件挂载前初始化地图
onBeforeMount(() => {
  initMap()
})

// 地图初始化完成回调
const onMapInited = () => {
  console.log(mapRef.value.map)
  console.log(markerRef.value.marker)
}

// 获取图层实例
const getLayerInstance = () => {
  console.log(markerRef.value.marker)
}

// 初始化地图
const initMap = () => {
  // 设置API密钥
  apiKey.value = import.meta.env.VITE_APP_MAP_KEY

  // 根据地址初始化地图
  console.log('🚀 ~ props.location.address:', props.location.address)
  if (props.location.address) {
    geoCoder()
  } else {
    // 获取当前位置
    getLocation(apiKey.value).then(res => {
      center.value = res.data.result.location
      geometries.value = [
        ...geometries.value,
        {
          styleId: 'marker',
          position: center.value
        }
      ]
    })
    console.log('🚀 ~ newValue:')
    navigation()
  }
}
function navigation() {
  if (props.navigation && props.navigation.destination) {
    // 添加起点标记
    geometries.value = [
      // ...geometries.value,
      {
        styleId: 'marker',
        position: props.navigation.current
      }
    ]
    // 设置中心点
    center.value = props.navigation.current

    // 获取并绘制导航路线
    getNavDriving(apiKey.value, props.navigation.current, props.navigation.destination).then(res => {
      let data = [...res.data.result.routes[0].polyline]
      let temp = []
      // 处理路线坐标数据
      for (let i = 2; i < data.length; i++) {
        data[i] = data[i - 2] + data[i] / 1000000
      }
      for (let j = 0; j < data.length; j += 2) {
        temp.push({
          lat: data[j],
          lng: data[j + 1]
        })
      }
      // 设置路线数据
      p_geometries.value = [
        {
          id: 1,
          styleId: 'polyline',
          paths: temp
        }
      ]
      // 添加终点标记
      geometries.value = [
        ...geometries.value,
        {
          styleId: 'marker',
          position: props.navigation.destination
        }
      ]
    })
  }
}
// 地理编码函数
function geoCoder() {
  getGeoCoder(apiKey.value, 'address', props.location.address).then(res => {
    const { result } = res.data
    center.value = result.location
    geometries.value = [...geometries.value, { styleId: 'marker', position: result.location }]
    emit('locationUpdate', result)
  })
}

// 地图点击事件处理
const onMapClick = e => {
  if (props.disabled) {
    return
  }
  getGeoCoder(apiKey.value, 'location', e.latLng).then(res => {
    const { result } = res.data
    geometries.value = [{ styleId: 'marker', position: result.location }]
    emit('locationUpdate', result)
  })
}
</script>

<style lang="less">
.map-container {
  height: 400px;
  border: 1px slategrey dashed;
  border-radius: 10px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
  canvas {
    border-radius: 10px;
  }
}
</style>
